package model

import (
	"fmt"
	"gowork/combinedQuery/pool"
	"time"
)

type Members struct {
	Id int64 `xorm:"pk autoincr"`
	Nickname string
	CustomerTypeId int
	CreatedAt time.Time
	UpdatedAt time.Time
}

type TotalAc struct {
	SumAchievement int64
	SumConsumptionAmount float64
}

type TotalConsumptionType struct {
	Id int
	Name string
	SumAchievement int64
	SumConsumptionAmount float64
	SumMembershipCard float64
	SumGiftMoney float64
	SumCash float64
	SumUnionPay float64
	SumAlipay float64
	SumWeChat float64
	SumGroupBuying float64
	SumCashCoupon float64
	SumArrears float64
}

type MeiyeOrders struct {
	Id int64 `xorm:"pk autoincr"`
	MemberId int64
	ConsumptionTypeId int
	PurchaseGoods string
	Achievement int64
	ConsumptionAmount float64
	Dissipate time.Time
}

type PaymentMethods struct {
	Id int `xorm:"pk autoincr"`
	PaymentName string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type TotalPayment struct {
	ConsumptionTypeId int
	PaymentMethodId int
	AmountOfMoney float64
}

type MeiyeOrderPayment struct {
	Id int64 `xorm:"pk autoincr"`
	MeiyeOrderId int64
	PaymentMethodId int
	AmountOfMoney float64
}

func NewMeiyeOrders() *MeiyeOrders{
	return new(MeiyeOrders)
}

func ErrorHandle(ct *TotalConsumptionType, taList []*TotalAc, index int){
	defer func(){
		err := recover()
		if err != nil{
			ct.SumConsumptionAmount = 0
			ct.SumConsumptionAmount = 0
		}
	}()

	ct.SumAchievement = taList[index].SumAchievement
	ct.SumConsumptionAmount = taList[index].SumConsumptionAmount
}

func (m *MeiyeOrders)StatisticalQuery(ms *MeiyeStatistical)([]*TotalConsumptionType, int, error){

	var session = x.NewSession()
	var sessionAcs = x.NewSession()

	session = session.Table("meiye_orders")
	sessionAcs = sessionAcs.Table("meiye_orders")

	if ms.DissipateStart != ""{
		session = session.Where("dissipate >= ?", ms.DissipateStart )
		sessionAcs = sessionAcs.Where("dissipate >= ?", ms.DissipateStart )
	}

	if ms.DissipateEnd != ""{
		session = session.Where("dissipate <= ?", ms.DissipateEnd )
		sessionAcs = sessionAcs.Where("dissipate <= ?", ms.DissipateEnd )
	}

	if ms.CustomerType != ""{

		session = session.Join("INNER", "members", "meiye_orders.member_id = members.id" ).
			Where("members.customer_type_id = ?", ms.CustomerType)
		sessionAcs = sessionAcs.Join("INNER", "members", "meiye_orders.member_id = members.id" ).
			Where("members.customer_type_id = ?", ms.CustomerType)
	}

	//if ms.Sort == 1{
	//	session = session.Asc("dissipate")
	//	sessionAcs = sessionAcs.Asc("dissipate")
	//}else if ms.Sort == 2{
	//	session = session.Desc("dissipate")
	//	sessionAcs = sessionAcs.Desc("dissipate")
	//}

	var acs []*TotalAc
	err := sessionAcs.Select("sum(meiye_orders.achievement) as sum_achievement, sum(meiye_orders.consumption_amount) as sum_consumption_amount").
		Join("LEFT", "meiye_order_payment", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		GroupBy("meiye_orders.consumption_type_id").
		OrderBy("meiye_orders.consumption_type_id asc").
		Find(&acs)
	fmt.Println(acs)
	if err != nil{
		return nil, 0, err
	}

	var tp []*TotalPayment
	err = session.Select("meiye_orders.consumption_type_id, meiye_order_payment.payment_method_id, meiye_order_payment.amount_of_money").
		Join("INNER", "meiye_order_payment", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		//Join("INNER", "payment_methods", "meiye_order_payment.payment_method_id = payment_methods.id").
		//GroupBy("meiye_orders.consumption_type_id").
		//GroupBy("meiye_order_payment.payment_method_id").
		//OrderBy("meiye_orders.consumption_type_id asc").
		Find(&tp)
	fmt.Println(tp)
	if err != nil{
		return nil, 0, err
	}

	var cts []*TotalConsumptionType
	var ct1  = TotalConsumptionType{
		Id:1,
		Name:"项目消费",
	}
	cts = append(cts, &ct1)
	var ct2  = TotalConsumptionType{
		Id:2,
		Name:"产品消费",
	}
	cts = append(cts, &ct2)
	var ct3  = TotalConsumptionType{
		Id:3,
		Name:"疗程套餐消费",
	}
	cts = append(cts, &ct3)
	var ct4  = TotalConsumptionType{
		Id:4,
		Name:"定制套餐消费",
	}
	cts = append(cts, &ct4)
	var ct5  = TotalConsumptionType{
		Id:5,
		Name:"开卡充值",
	}
	cts = append(cts, &ct5)

	for _, t := range cts{

		ErrorHandle(t, acs, t.Id-1)

		//sumMembershipCard, err := session.Join("INNER", "meiye_orders", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		//	Where("meiye_orders.consumption_type_id = ?", t.Id).
		//	And("meiye_order_payment.payment_method_id = ?",1).
		//	Sum(new(MeiyeOrderPayment), "amount_of_money")
		//if err != nil{
		//	return nil, 0, err
		//}
		//t.SumMembershipCard = sumMembershipCard
		//
		//sumGiftMoney, err := session.Join("INNER", "meiye_orders", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		//	Where("meiye_orders.consumption_type_id = ?", t.Id).
		//	And("meiye_order_payment.payment_method_id = ?",2).
		//	Sum(new(MeiyeOrderPayment), "amount_of_money")
		//if err != nil{
		//	return nil, 0, err
		//}
		//t.SumGiftMoney = sumGiftMoney

		for _, v := range tp {
			if t.Id == v.ConsumptionTypeId {
				switch v.PaymentMethodId {
				case 1:
					t.SumMembershipCard += v.AmountOfMoney
				case 2:
					t.SumGiftMoney += v.AmountOfMoney
				case 3:
					t.SumCash += v.AmountOfMoney
				case 4:
					t.SumUnionPay += v.AmountOfMoney
				case 5:
					t.SumAlipay += v.AmountOfMoney
				case 6:
					t.SumWeChat += v.AmountOfMoney
				case 7:
					t.SumGroupBuying += v.AmountOfMoney
				case 8:
					t.SumCashCoupon += v.AmountOfMoney
				case 9:
					t.SumArrears += v.AmountOfMoney
				default:

				}
			}
		}
	}

	totals := len(cts)

	if totals < ms.PageSize*ms.PageNo && totals > (ms.PageNo-1)*ms.PageSize{
		return cts[(ms.PageNo-1)*ms.PageSize:], totals, nil
	}

	if totals <= (ms.PageNo-1)*ms.PageSize{
		return nil, 0, nil
	}

	return cts[(ms.PageNo-1)*ms.PageSize:ms.PageNo*ms.PageSize], totals, nil
}

func (m *MeiyeOrders)StatisticalQueryAsync(ms *MeiyeStatistical)([]*TotalConsumptionType, int, error){

	var session = x.NewSession()
	var sessionAcs = x.NewSession()

	session = session.Table("meiye_orders")
	sessionAcs = sessionAcs.Table("meiye_orders")

	if ms.DissipateStart != ""{
		session = session.Where("dissipate >= ?", ms.DissipateStart )
		sessionAcs = sessionAcs.Where("dissipate >= ?", ms.DissipateStart )
	}

	if ms.DissipateEnd != ""{
		session = session.Where("dissipate <= ?", ms.DissipateEnd )
		sessionAcs = sessionAcs.Where("dissipate <= ?", ms.DissipateEnd )
	}

	if ms.CustomerType != ""{

		session = session.Join("INNER", "members", "meiye_orders.member_id = members.id" ).
			Where("members.customer_type_id = ?", ms.CustomerType)
		sessionAcs = sessionAcs.Join("INNER", "members", "meiye_orders.member_id = members.id" ).
			Where("members.customer_type_id = ?", ms.CustomerType)
	}

	//if ms.Sort == 1{
	//	session = session.Asc("dissipate")
	//	sessionAcs = sessionAcs.Asc("dissipate")
	//}else if ms.Sort == 2{
	//	session = session.Desc("dissipate")
	//	sessionAcs = sessionAcs.Desc("dissipate")
	//}

	var acs []*TotalAc
	err := sessionAcs.Select("sum(meiye_orders.achievement) as sum_achievement, sum(meiye_orders.consumption_amount) as sum_consumption_amount").
		Join("LEFT", "meiye_order_payment", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		GroupBy("meiye_orders.consumption_type_id").
		OrderBy("meiye_orders.consumption_type_id asc").
		Find(&acs)
	fmt.Println(acs)
	if err != nil{
		return nil, 0, err
	}

	var tp []*TotalPayment
	err = session.Select("meiye_orders.consumption_type_id, meiye_order_payment.payment_method_id, meiye_order_payment.amount_of_money").
		Join("INNER", "meiye_order_payment", "meiye_orders.id = meiye_order_payment.meiye_order_id").
		//Join("INNER", "payment_methods", "meiye_order_payment.payment_method_id = payment_methods.id").
		//GroupBy("meiye_orders.consumption_type_id").
		//GroupBy("meiye_order_payment.payment_method_id").
		//OrderBy("meiye_orders.consumption_type_id asc").
		Find(&tp)
	fmt.Println(tp)
	if err != nil{
		return nil, 0, err
	}

	var cts []*TotalConsumptionType
	var ct1  = TotalConsumptionType{
		Id:1,
		Name:"项目消费",
	}
	cts = append(cts, &ct1)
	var ct2  = TotalConsumptionType{
		Id:2,
		Name:"产品消费",
	}
	cts = append(cts, &ct2)
	var ct3  = TotalConsumptionType{
		Id:3,
		Name:"疗程套餐消费",
	}
	cts = append(cts, &ct3)
	var ct4  = TotalConsumptionType{
		Id:4,
		Name:"定制套餐消费",
	}
	cts = append(cts, &ct4)
	var ct5  = TotalConsumptionType{
		Id:5,
		Name:"开卡充值",
	}
	cts = append(cts, &ct5)

	p := pool.NewSimplePoll(2)
	for i := 0; i < 2; i++ {
		var finalI int = i
		var end int = 0
		if i == 0{
			end = 2
		}else {
			end = len(cts)
		}
		p.Add(func() {
			for _, t := range cts[finalI*2:end]{

				ErrorHandle(t, acs, t.Id-1)

				//sumMembershipCard, err := session.Join("INNER", "meiye_orders", "meiye_orders.id = meiye_order_payment.meiye_order_id").
				//	Where("meiye_orders.consumption_type_id = ?", t.Id).
				//	And("meiye_order_payment.payment_method_id = ?",1).
				//	Sum(new(MeiyeOrderPayment), "amount_of_money")
				//if err != nil{
				//	return nil, 0, err
				//}
				//t.SumMembershipCard = sumMembershipCard
				//
				//sumGiftMoney, err := session.Join("INNER", "meiye_orders", "meiye_orders.id = meiye_order_payment.meiye_order_id").
				//	Where("meiye_orders.consumption_type_id = ?", t.Id).
				//	And("meiye_order_payment.payment_method_id = ?",2).
				//	Sum(new(MeiyeOrderPayment), "amount_of_money")
				//if err != nil{
				//	return nil, 0, err
				//}
				//t.SumGiftMoney = sumGiftMoney

				for _, v := range tp {
					if t.Id == v.ConsumptionTypeId {
						switch v.PaymentMethodId {
						case 1:
							t.SumMembershipCard += v.AmountOfMoney
						case 2:
							t.SumGiftMoney += v.AmountOfMoney
						case 3:
							t.SumCash += v.AmountOfMoney
						case 4:
							t.SumUnionPay += v.AmountOfMoney
						case 5:
							t.SumAlipay += v.AmountOfMoney
						case 6:
							t.SumWeChat += v.AmountOfMoney
						case 7:
							t.SumGroupBuying += v.AmountOfMoney
						case 8:
							t.SumCashCoupon += v.AmountOfMoney
						case 9:
							t.SumArrears += v.AmountOfMoney
						default:

						}
					}
				}
			}
		})
	}
	p.Run()

	totals := len(cts)

	if totals < ms.PageSize*ms.PageNo && totals > (ms.PageNo-1)*ms.PageSize{
		return cts[(ms.PageNo-1)*ms.PageSize:], totals, nil
	}

	if totals <= (ms.PageNo-1)*ms.PageSize{
		return nil, 0, nil
	}

	return cts[(ms.PageNo-1)*ms.PageSize:ms.PageNo*ms.PageSize], totals, nil
}